package com.lswsjw.android.lib.sqlite;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * @author limtaekyu DBOpenHelper
 */
public abstract class DBOpenHelper extends SQLiteOpenHelper
{
    
    public static final int READ_ONLY = 0;
    
    public static final int READ_WRITE = 1;
    
    private String mDBPath;
    
    private String mDBName;
    
    private String mRealPath;
    
    private Context mContext;
    
    protected SQLiteDatabase mDataBase;
    
    /**
     * @param context
     * @param name
     *            DataBase Name
     * @param factory
     * @param version
     *            DataBase Version
     * @param packageName
     *            Package name of application that use this library
     */
    public DBOpenHelper(Context context, String name, CursorFactory factory,
            int version, String packageName)
    {
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
        
        this.mDBPath = "/mnt/sdcard/data/" + packageName + "/databases/";
        this.mDBName = name;
        this.mRealPath = this.mDBPath + this.mDBName;
        this.mContext = context;
    }
    
    // public void createDataBaseFromFile()
    // {
    // try {
    // this.getReadableDatabase();
    // copyDataBase();
    // }
    // catch (IOException ioe)
    // {
    // }
    // }
    //
    // public void createDataBaseFromSql(String sql)
    // {
    // mDataBase.execSQL(sql);
    // }
    
    public abstract void createDataBase();
    
    /**
     * 
     * @param openMode
     *            READ_ONLY or READ_WRITE
     * @return
     */
    public SQLiteDatabase getDataBase(int openMode)
            throws WrongParameterException, SQLiteException
    {
        boolean dbExist = this.checkDataBase();
        
        if (!dbExist)
        {
            createDataBase();
        }
        
        if (openMode == READ_ONLY)
            mDataBase = SQLiteDatabase
                    .openDatabase(mRealPath, null, SQLiteDatabase.OPEN_READONLY);
        else if (openMode == READ_WRITE)
            mDataBase = SQLiteDatabase
                    .openDatabase(mRealPath, null,
                                  SQLiteDatabase.OPEN_READWRITE);
        else
            throw new WrongParameterException();
        
        return mDataBase;
    }
    
    private boolean checkDataBase()
    {
        SQLiteDatabase checkDB = null;
        
        try
        {
            
            checkDB = SQLiteDatabase.openDatabase(mRealPath, null,
                                                  SQLiteDatabase.OPEN_READONLY);
            
        }
        catch (SQLiteException e)
        {
            // database does't exist yet.
        }
        
        if (checkDB != null)
        {
            checkDB.close();
            return true;
        }
        
        return false;
    }
    
    public void copyDataBase() throws IOException, NullPointerException
    {
        InputStream is = this.mContext.getAssets().open(this.mDBName);
        File path = new File(this.mDBPath);
        if(!path.exists())
        	path.mkdirs();
        String outFileName = this.mDBPath + this.mDBName;
        File outFile = new File(outFileName);
        OutputStream os = new FileOutputStream(outFile);
        
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) > 0)
        {
            os.write(buffer, 0, length);
        }
        
        os.flush();
        os.close();
        is.close();
    }
    
    @Override
    public synchronized void close()
    {
        // TODO Auto-generated method stub
        mDataBase.close();
        super.close();
    }
    
    @Override
    public void onCreate(SQLiteDatabase db)
    {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        // TODO Auto-generated method stub
        if (oldVersion < newVersion)
        {
            // Drop
            // Create
        }
    }
    
}
